package com.tmtc.utils.secret;

import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import javax.crypto.Cipher;
import javax.xml.rpc.ServiceException;

import com.google.gson.Gson;
import com.tmtc.vo.recharge.Result;

/**
 * RSA安全编码组件
 * 
 * @author 梁栋
 * @version 1.0
 * @since 1.0
 */
public abstract class SRSACoder extends Coder {
	private static final String KEY_ALGORITHM = "RSA";
	private static final String SIGNATURE_ALGORITHM = "MD5withRSA";
	private static final String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCzqpszEZ/kOV0YCV+Qcf721RyE8VlN7L46Ux4TjerBniinL1iSlBb/OP1Vm5S16eo9Cy/mekyTB6aXhT4eF9KVm+npbfusx+Q9cf6SB/AY0amISuFatHrRbOf1YCVUgjBDedhH52HzMk44V0bIkeE7vp40E9hpCkHO2aJI1UynccTfpnvPC51UAfk8cxjbfAFxfZ88gVHWcbzt0eqTf5TSKMyjjODzgvTfI+L1hw4L3uJOo7yKXWWzMHidQ1oGF9RDDPCf1DhVwnSCwolKm+Dj65FC7WuE2fET+wKROb9hej1KUVKC8sCVkOh0XelElqfS5xEEhAf8aFNIcEbcqKbhAgMBAAECggEAW48X5GCY8P9it7sfHkdZvYRBMmakMhfxoVt2OlTaS61D3l88bgZV6d6rC5Nrp4D7Q/yNfpDYsRz3AsR+MWvGf0OjYrgPx69eWwnax6SP8LX4BWLTkRvkcxFi7CMBIx3tZpWTaKE7w2nhfsjLY68j7wRnLvbmFDGL89Po5eD9XV68QgHWH82jQjE7Tef3Yulw5ffHe2N3rFFPt+Xr9f8sP0RDqCfseBgle7RPmLp+BCXoiJqXtylJK6MMIA7whjPEpUnNoXCcdFLH03k7vwJRXD+/3nZg1I6pdtWIQhulCJfdQv+Rv/e03o7M9+Rh5eXAVfBdoR5mneV1AwDMTT+wWQKBgQDf2aBZ/xxdw68lM/lZlVqSjxTwf/gcwr7SnOSmniA2vsg3FX7Nr+qmkqo6ShGEE5RIm/xwDJrF6agIC/YuPYJq9ztl4bzUmSa5wzvMwC+scZ57vAk6bXU4Derwi4+IeVjum497ybsSwnJ++kqKPHkvEIWRXGdRTdCuS6oKNiHKvwKBgQDNeHavkuwFU04r9XDkRkMhaOlSr0SckruzArbvpIcCeVmpxbUAbErExamaGRm4ZnxjSW7tTrwTWuCi8x2cso1DssH9cwhWCieWF2/uWMxSoJ7irMFWD5BGnil22hzEzUO9f5w6V9QaQOqpI1t8gnf25igDdHLu2YwUGPvGh84WXwKBgQCZr62y/D66dXZTYYqpoawMgWXL9OAgxugCa6tkZZ4SWAvYHc7wYv4EnR94Y5ABEPw2mbnIKC8/ADvYQnYjqyFWVSWXvlNJ11hKI6tz2OMiTuOTajcfwTTAZnXN7tN9zGptb6okQA1LROsdGLSCkiBVWs+JTFq27GkAsXwuBJpQuwKBgQDItuiZ0pglC5/NaVICbHCfbnCeiQApQ12AHSK/LqWEUS65nZyW8TKIzd5D3kk1zUetZcqqnsMy1Q+jnoJK1FES1MiT4Y8/HWRWRkbdOnk+LhGHtOKYQ1PY6B/xLlf0F+AYeVQP2kQj8U5KM3PnSTwPP/3Ogi7UDEe+SjmJUpiLWQKBgAKHZR/aU4GSI9rh8BaVFnCGpKZUrmbJa8pxqr+jidnFJrw3i2oHdBdR5kXtAiY5KdE1fZHdWO0CsYMyL+lpOH1ApV60LHq2xyTdMTKHjwLkTlnooYGSwlPlJQowBgz9PoInzHN0s7oT9cvjSBimYF8589RKEy4oEIqzwrdUz0Wo";

	/**
	 * 傻一
	 */
	private static final String SIGN_ALGORITHMS = "SHA1WithRSA";

	/**
	 * 用私钥对信息生成数字签名
	 * 
	 * @param data
	 *            加密数据
	 * @return
	 * @throws Exception
	 */
	public static Object sign(Object object) throws Exception {
		Gson gson = new Gson();
		String json = gson.toJson(object);
		byte[] data = json.getBytes();
		byte[] bs = encryptByPrivateKey(data);
		Result result = new Result(encryptByPrivateKey(json), sign(bs));
		return result;
	}

	/**
	 * RSA签名  sha1
	 * 
	 * @param data
	 * @return 签名值
	 */
	public static String sign1(byte[] data) {
		try {
			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(PRIVATE_KEY));
			KeyFactory keyf = KeyFactory.getInstance(KEY_ALGORITHM);
			PrivateKey priKey = keyf.generatePrivate(priPKCS8);
			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
			signature.initSign(priKey);
			signature.update(data);
			byte[] signed = signature.sign();
			return Base64.encode(signed);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 用私钥对信息生成数字签名   md5
	 * 
	 * @param data
	 *            加密数据
	 * @return
	 * @throws Exception
	 */
	private static String sign(byte[] data) throws Exception {

		// 解密由base64编码的私钥
		byte[] keyBytes = decryptBASE64(PRIVATE_KEY);
		// 构造PKCS8EncodedKeySpec对象
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		// KEY_ALGORITHM 指定的加密算法
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		// 取私钥匙对象
		PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
		// 用私钥对信息生成数字签名
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initSign(priKey);
		signature.update(data);
		return encryptBASE64(signature.sign());
	}
	
//	public static void main(String[] args) {
//		String s = "CNzIT0ar7OGy8Dgdp6KkLBI2qIdEZVROh5127sBtCbKsY8UVpOeJIqJMDV4PkigE4gtP0XZMq8Q+990tsvvXrkih53PH0Sp7NrCiQNGnj9VMhxcj8M3a5qc5tXKEuQFqmCze8hphRL8qzdZIKHjL1lVfDlHJXt8ersX7zYKkCgC3BaAVupkGHKqeqmcoSuL3356DnHEj6Oy+BB6UGlfT8/LQP+qjxLjPJvuokILY1UAIpMRjm5WLIfJT67oypcoAqn/8WsTHxDDWbjd6XS9iD1h/zY1bFrJMawhkFEvfjImMjvWrfwmLCRYbrIQqjhpxPzPzbz0y98Y9vUsfm6zTm/pH+CeSewbaiQZ0UDAnpzNHRV6TJGc0FRor3VwZWZ4NceiWvmLP?h2wmhq8LQlMv5hlr7zFyPqQzg2gem761ClubCCwpZq0UCyHbtXPD8mZlokvYZxyfAYLadpDYzTw4tddMoZ+NVq8OGvYCLWulXkzF8BCDpOU=";
//		String decryptByPrivateKey = decryptByPrivateKey(s);
//		System.out.println(decryptByPrivateKey);
//	}

	/**
	 * 解密<br>
	 * 用私钥解密
	 * 
	 * @param string
	 *            (经过base64加密后的字符串)
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String decryptByPrivateKey(String string) {
		byte[] data = null;
		byte[] bs = null;
		try {
			data = Coder.decryptBASE64(string);
			bs = decryptByPrivateKey(data);
		} catch (Exception e) {
			new ServiceException("RSA解密失败！");
			return null;
		}
		return new String(bs);
	}

	/**
	 * 解密<br>
	 * 用私钥解密
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	private static byte[] decryptByPrivateKey(byte[] data) throws Exception {

		// 对密钥解密
		byte[] keyBytes = decryptBASE64(PRIVATE_KEY);

		// 取得私钥
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

		// 对数据解密
		// Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.DECRYPT_MODE, privateKey);

		return cipher.doFinal(data);
	}

	/**
	 * 加密<br>
	 * 用私钥加密
	 * 
	 * @param string
	 * @return
	 * @throws Exception
	 */
	public static String encryptByPrivateKey(String string) {
		String str = null;
		try {
			str = encryptBASE64(encryptByPrivateKey(string.getBytes()));
		} catch (Exception e) {
			new ServiceException("RSA加密失败！");
			e.printStackTrace();
		}
		return str;
	}

	/**
	 * 加密<br>
	 * 用私钥加密
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	private static byte[] encryptByPrivateKey(byte[] data) throws Exception {

		// 对密钥解密
		byte[] keyBytes = decryptBASE64(PRIVATE_KEY);

		// 取得私钥
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

		// 对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
		return cipher.doFinal(data);
	}
}